/* eslint-disable no-console */
const WeatherUtils = (() => {
    // 定位服务配置
    const LOCATION_CONFIG = {
        cacheTTL: 15 * 60 * 1000,    // 15分钟缓存时间
        gpsTimeout: 5000,            // GPS 定位超时时间（毫秒）
        ipAccuracy: 5000,            // IP 定位默认精度(米)
        ipProviders: [
            'https://ipapi.co/json/',
            'https://ipinfo.io/json',
            'https://geolocation-db.com/json/'
        ]
    }

    /**
     * 从本地存储获取缓存位置
     * @returns {{
     *   data: {lat: number, lng: number, source: string, accuracy: number},
     *   timestamp: number
     * }|null} - 位置数据和时间戳
     */
    async function getLocationFromStorage() {
        try {
            const cached = await window.__cacheManager.getConfig('location', 'currentLocation');

            if (!cached) return null;

            if (!cached.data || !cached.timestamp) return null;

            return cached;
        } catch (error) {
            console.debug('读取位置缓存失败:', error);
            return null;
        }
    }

    /**
     * 保存位置到本地存储
     * @param {object} location - 位置数据
     */
    async function saveLocationToStorage(location) {
        try {
            const cacheData = {
                data: location,
                timestamp: Date.now()
            };
            await window.__cacheManager.setConfig('location', 'currentLocation', cacheData)
        } catch (error) {
            console.debug('保存位置缓存失败:', error);
        }
    }

    /**
     * 从多个IP定位服务获取位置信息
     * @returns {Promise<{lat: number, lng: number, source: string, accuracy: number, fromStorage: boolean}|null>} - 位置信息
     */
    async function getIPLocation() {
        // 尝试所有可用的IP定位服务
        for (const provider of LOCATION_CONFIG.ipProviders) {
            try {
                const response = await fetch(provider);
                if (!response.ok) continue;

                const ipData = await response.json();
                if (ipData.latitude && ipData.longitude) {
                    return {
                        lat: Number.parseFloat(ipData.latitude.toFixed(2)),
                        lng: Number.parseFloat(ipData.longitude.toFixed(2)),
                        source: 'ip',
                        accuracy: Number.parseFloat(LOCATION_CONFIG.ipAccuracy.toFixed(2)),
                        fromStorage: false
                    };
                } else if (ipData.loc) {
                    const [lat, lng] = ipData.loc.split(',');
                    return {
                        lat: Number.parseFloat(lat.toFixed(2)), // 纬度（-90~90）
                        lng: Number.parseFloat(lng.toFixed(2)), // 经度（-180~180）
                        source: 'ip',
                        accuracy: Number.parseFloat(LOCATION_CONFIG.ipAccuracy.toFixed(2)),
                        fromStorage: false
                    };
                }
            } catch (error) {
                console.debug(`${provider} 定位失败:`, error);
            }
        }
        return null;
    }

    /**
     * 检查地理位置权限状态
     * @returns {Promise<{state: string, canRequest: boolean}>} - 权限状态和是否可请求
     */
    async function checkGeolocationPermission() {
        const result = {
            state: 'prompt',
            canRequest: true
        };

        try {
            if (!navigator.permissions?.query) {
                result.state = 'geolocation' in navigator ? 'prompt' : 'unsupported';
                return result;
            }

            const permissionStatus = await navigator.permissions.query({
                name: 'geolocation'
            });

            result.state = permissionStatus.state;
            result.canRequest = permissionStatus.state === 'granted';

        } catch (error) {
            console.debug('权限检查异常:', error);
        }

        return result;
    }

    /**
     * 获取GPS定位信息
     * @returns {Promise<{lat: number, lng: number, source: string, accuracy: number, fromStorage: boolean}|null>} - 位置信息
     */
    async function getGPSLocation() {
        try {
            // 先检查API支持性（同步检查）
            if (!navigator.geolocation) {
                throw new Error('浏览器不支持地理位置API');
            }

            // 创建可取消的Promise
            let abortController;
            try {
                abortController = new AbortController();
                // 移除了未使用的 const { signal } = abortController;

                // 主定位请求
                const position = await Promise.race([
                    // 主定位请求
                    new Promise((resolve, reject) => {
                        navigator.geolocation.getCurrentPosition(
                            resolve,
                            reject,
                            {
                                enableHighAccuracy: true,             // 是否尝试高精度定位
                                timeout: LOCATION_CONFIG.gpsTimeout,  // 请求超时时间(毫秒)
                                maximumAge: 0                         // 可接受的最大缓存位置年龄(毫秒)，设为 0 表示必须获取新位置，根据使用场景调整，如高精度场景（地图导航）、低功耗场景（天气应用）等
                            }
                        );
                    }),
                    // 超时/安全策略检测
                    new Promise((_, reject) => {
                        setTimeout(() => {
                            reject(new Error('GEOLOCATION_TIMEOUT_OR_BLOCKED'));
                        }, 100); // 短时间检测是否被浏览器拦截
                    })
                ]);

                // console.debug('GPS定位成功:', position);
                return {
                    lat: Number.parseFloat(position.coords.latitude.toFixed(2)),
                    lng: Number.parseFloat(position.coords.longitude.toFixed(2)),
                    source: 'gps',
                    accuracy: Number.parseFloat(position.coords.accuracy.toFixed(2)),
                    fromStorage: false
                };
            } finally {
                if (abortController) {
                    abortController.abort(); // 清理可能的残留请求
                }
            }
        } catch (error) {
            // 识别被浏览器拦截的情况
            if (error.message.includes('user gesture') || error.message === 'GEOLOCATION_TIMEOUT_OR_BLOCKED') {
                // console.debug('定位请求被浏览器安全策略阻止');
                return null;
            }
            console.debug('GPS定位失败:', error);
            return null;
        }
    }

    /**
     * 获取缓存位置或新位置
     * @returns {Promise<{lat: number, lng: number, source: string, accuracy: number, fromStorage: boolean}|null>} - 位置信息
     */
    async function getCachedLocation() {

        // 尝试从本地存储获取缓存
        const cached = await getLocationFromStorage();

        // 检查有效缓存
        if (cached && Date.now() - cached.timestamp < LOCATION_CONFIG.cacheTTL) {
            // console.debug('使用缓存位置');
            return {
                ...cached.data,
                fromStorage: true
            };
        }

        // 获取新位置
        const location = await getFreshLocation();
        if (location) {
            // 保存到本地存储
            await saveLocationToStorage(location);
        }
        return location;
    }

    /**
     * 获取最新位置信息
     * @returns {Promise<{lat: number, lng: number, source: string, accuracy: number, fromStorage: boolean}|null>} - 最新位置信息
     */
    async function getFreshLocation() {
        try {
            // 检查权限状态
            const {canRequest} = await checkGeolocationPermission();
            // console.debug(`位置权限状态: ${state}, 可请求: ${canRequest}`);

            // 优先尝试GPS定位
            if (canRequest) {
                const gpsLocation = await getGPSLocation();
                if (gpsLocation) return gpsLocation;
            }

            // 回退到IP定位
            return await getIPLocation();

        } catch (error) {
            console.error('获取位置异常:', error);
            return await getIPLocation();
        }
    }

    return {
        /**
         * 获取最佳可能位置（带缓存）
         * @returns {Promise<{lat: number, lng: number, source: string, accuracy: number, fromStorage: boolean}|null>} - 最佳位置信息
         */
        getBestPossibleLocation: async () => {
            return await getCachedLocation();
        }
    };
})();

export { WeatherUtils };